package com.gzdh.tang.ali.rule;

import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.gzdh.tang.ali.model.OuterExtends;
import com.gzdh.tang.comm.constant.SpringContextUtils;
import com.gzdh.tang.comm.handler.IPayRuleHandler;
import com.gzdh.tang.config.weixin.WXEntity;
import com.gzdh.tang.mobile.entity.Kl;
import com.gzdh.tang.mobile.service.KlService;
import com.gzdh.tang.modu.entity.Fk;
import com.gzdh.tang.modu.entity.MacMainpSbruan;
import com.gzdh.tang.modu.entity.MacMainpSbruanDinner;
import com.gzdh.tang.modu.model.QrRestrictionsModel;
import com.gzdh.tang.modu.service.*;
import com.gzdh.tang.modu.util.DateUtil;
import com.gzdh.tang.warehouse.service.DeviceService;
import com.gzdh.tang.warehouse.service.InStockService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;

import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.*;

/**
 * 民政医院的核销方案
 */
@Slf4j
public class AliMinZhenRule implements IPayRuleHandler {

    FkService fkService;

    GsService gsService;

    MacMainpSbruanService macMainpSbruanService;

    MacMainpSbruanDinnerService macMainpSbruanDinnerService;

    MacMainpSbruanKlService macMainpSbruanKlService;

    ReserveService reserveService;

    TangDeviceService tangDeviceService;

    DeviceService deviceService;

    InStockService inStockService;


    MacMainpSbruanKlDinnerService macMainpSbruanKlDinnerService;

    MacMainpSbruanKlButieService macMainpSbruanKlButieService;
    KlService klService;

    public AliMinZhenRule() {
        fkService = (FkService) SpringContextUtils.getBean("fkServiceImpl");
        gsService = (GsService) SpringContextUtils.getBean("gsService");
        macMainpSbruanService = (MacMainpSbruanService) SpringContextUtils.getBean("macMainpSbruanService");
        macMainpSbruanDinnerService = (MacMainpSbruanDinnerService) SpringContextUtils.getBean("macMainpSbruanDinnerService");
        macMainpSbruanKlService = (MacMainpSbruanKlService) SpringContextUtils.getBean("macMainpSbruanKlService");
        reserveService = (ReserveService) SpringContextUtils.getBean("reserveService");
        tangDeviceService = (TangDeviceService) SpringContextUtils.getBean("tangDeviceServiceImpl");
        deviceService = (DeviceService) SpringContextUtils.getBean("deviceServiceImpl");
        inStockService = (InStockService) SpringContextUtils.getBean("inStockService");
        macMainpSbruanKlDinnerService = (MacMainpSbruanKlDinnerService) SpringContextUtils.getBean("macMainpSbruanKlPriceService");
        macMainpSbruanKlButieService = (MacMainpSbruanKlButieService) SpringContextUtils.getBean("macMainpSbruanKlButieService");
        klService = (KlService) SpringContextUtils.getBean("klService");
    }

    @Override
    public JSONObject toCardPay(JSONObject params) throws RuntimeException {
        String deviceId = params.getString("deviceId");
        String price = params.getString("price");
        String cardsn = params.getString("cardsn");
        String orders = params.getString("orders");
        String dateStr = params.getString("dateStr");
        JSONObject jsonObject = new JSONObject();
        jsonObject.putAll(params);
        try {
            Fk fk = fkService.getOne(new QueryWrapper<Fk>().lambda().eq(Fk::getCardsn, cardsn));
            if (fk == null) {
                throw new RuntimeException("非法卡");
            }
            Kl kl = klService.getOne(new QueryWrapper<Kl>().lambda().eq(Kl::getBm, fk.getKl()));
            if (kl != null && kl.getValid() == 1) {
                //判断有效期
                if (fk.getValiddate().compareTo(new Date()) < 0) {
                    throw new RuntimeException("超过有效期");
                }
            }
            MacMainpSbruan macMainpSbruan = macMainpSbruanService
                    .getOne(new QueryWrapper<MacMainpSbruan>().lambda().eq(MacMainpSbruan::getMac, deviceId));
            try {
                String dinner = getDinner(macMainpSbruan).trim();
                macMainpSbruan.setDinner(dinner);
            } catch (Exception e) {
                e.printStackTrace();
                throw new RuntimeException("餐次获取失败");
            }

            Map<String, String> resMap = reserveService.hexiaoReserve(Integer.parseInt(fk.getCardno()), macMainpSbruan.getDinner());
            if ("-1".equals(resMap.get("code")) || "-2".equals(resMap.get("code"))) {
                //支付失败
                throw new RuntimeException(resMap.get("msg"));
            } else if ("1".equals(resMap.get("code"))) {
                //支付成功，都不需要操作
                log.info("支付成功");
            } else if ("0".equals(resMap.get("code"))) {
                //可以支付，但支付不成功
                BigDecimal prices = new BigDecimal(resMap.get("payPrice"));
                int orderCount = Integer.parseInt(resMap.get("reserveSize"));
                reserveService.toPayByCardNo(deviceId, prices.multiply(new BigDecimal(100)).intValue(),
                        fk.getCardno(), orders, orderCount + 1);
                price = prices.toPlainString();
            }
            if (StringUtils.isEmpty(price)) {
                price = "0";
            }
            jsonObject.put("fk", fk);
            jsonObject.put("success", true);
            jsonObject.put("msg", "支付成功");
            jsonObject.put("userName", fk.getName());
            jsonObject.put("amount", price);
            List<OuterExtends> outerExtendsList = new ArrayList<>();
            outerExtendsList.add(addOutOuterExtends("姓名", fk.getName()));
            outerExtendsList.add(addOutOuterExtends("消费金额", price));
            outerExtendsList.add(addOutOuterExtends("卡余额", fk.getKye()));
            outerExtendsList.add(addOutOuterExtends("补贴余额", fk.getBtye()));
            jsonObject.put("outerExtends", outerExtendsList);
        } catch (Exception e) {
            e.printStackTrace();
            jsonObject.put("success", false);
            jsonObject.put("msg", e.getMessage());
        }
        return jsonObject;
    }

    @Override
    public JSONObject toCashPay(JSONObject params) throws RuntimeException {
        return null;
    }

    @Override
    public JSONObject toQrPay(JSONObject params) throws RuntimeException {
        JSONObject jsonObject = new JSONObject();
        jsonObject.putAll(params);
        //授权码，付款码或者电子饭卡
        String auth = params.getString("authCode");
        int authType = 0;
        if (auth.length() < 19 && "1".equals(auth.substring(0, 1))) {
            //微信
            jsonObject.putAll(weixinQrPay(params));
        } else if (auth.length() < 19 && "2".equals(auth.substring(0, 1))) {
            //支付宝
            jsonObject.putAll(aliQrPay(params));
        } else {
            //其他，需要解码
            jsonObject.putAll(dzkPay(params));
        }
        return jsonObject;
    }

    @Override
    public JSONObject toFacePay(JSONObject params) throws RuntimeException {
        JSONObject jsonObject = new JSONObject();
        jsonObject.putAll(params);
        log.info("接收参数：" + params.toString());
        try {
            SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmss");
            String deviceId = params.getString("deviceId");
            String price = params.getString("price");
            String authCode = params.getString("faceToken");
            String orders = sdf.format(new Date()) + deviceId;
            String aliUid = params.getString("aliUid");
            String terminalParams = params.getString("terminal_params");
            System.out.println("接收授权码:" + aliUid);
            Fk fk = fkService.getOne(new QueryWrapper<Fk>().lambda().eq(Fk::getAliUserId, aliUid));
            if (fk == null) {
                throw new RuntimeException("查无此人");
            }
            Kl kl = klService.getOne(new QueryWrapper<Kl>().lambda().eq(Kl::getBm, fk.getKl()));
            if (kl != null && kl.getValid() == 1) {
                //判断有效期
                if (fk.getValiddate().compareTo(new Date()) < 0) {
                    throw new RuntimeException("超过有效期");
                }
            }
            MacMainpSbruan macMainpSbruan = macMainpSbruanService.getOne(new QueryWrapper<MacMainpSbruan>().lambda().eq(MacMainpSbruan::getMac, deviceId));
            try {
                String dinner = getDinner(macMainpSbruan).trim();
                macMainpSbruan.setDinner(dinner);
            } catch (Exception e) {
                e.printStackTrace();
                throw new RuntimeException("餐次获取失败");
            }

            Map<String, String> resMap = reserveService.hexiaoReserve(Integer.parseInt(fk.getCardno()), macMainpSbruan.getDinner());
            if ("-1".equals(resMap.get("code")) || "-2".equals(resMap.get("code"))) {
                //支付失败
                throw new RuntimeException(resMap.get("msg"));
            } else if ("1".equals(resMap.get("code"))) {
                //支付成功，都不需要操作
                log.info("支付成功");
            } else if ("0".equals(resMap.get("code"))) {
                //可以支付，但支付不成功
                BigDecimal prices = new BigDecimal(resMap.get("payPrice"));
                int orderCount = Integer.parseInt(resMap.get("reserveSize"));
                reserveService.toPayByCardNo(deviceId, prices.multiply(new BigDecimal(100)).intValue(),
                        fk.getCardno(), orders, orderCount + 1);
                price = prices.toPlainString();
            }
            if (StringUtils.isEmpty(price)) {
                price = "0";
            }
            jsonObject.put("fk", fk);
            jsonObject.put("success", true);
            jsonObject.put("msg", "支付成功");
            jsonObject.put("userName", fk.getName());
            jsonObject.put("amount", price);
            List<OuterExtends> outerExtendsList = new ArrayList<>();
            outerExtendsList.add(addOutOuterExtends("姓名", fk.getName()));
            outerExtendsList.add(addOutOuterExtends("消费金额", price));
            outerExtendsList.add(addOutOuterExtends("卡余额", fk.getKye()));
            outerExtendsList.add(addOutOuterExtends("补贴余额", fk.getBtye()));
            jsonObject.put("outerExtends", outerExtendsList);
        } catch (Exception e) {
            e.printStackTrace();
            jsonObject.put("success", false);
            jsonObject.put("msg", e.getMessage());
        }
        return jsonObject;
    }

    public JSONObject weixinQrPay(JSONObject params) {
        WXEntity wxEntity = new WXEntity();
        JSONObject jsonObject = new JSONObject();
        String price = params.getString("price");
        price = new BigDecimal(price).multiply(new BigDecimal(100)).stripTrailingZeros().toPlainString();
        String orders = params.getString("orders");
        String auth = params.getString("auth");
        String deviceId = params.getString("deviceId");
        jsonObject.put("success", false);
        jsonObject.put("msg", "请使用电子饭卡");
        return jsonObject;
    }

    //支付宝二维码支付
    public JSONObject aliQrPay(JSONObject params) {
        JSONObject jsonObject = new JSONObject();
        String deviceId = params.getString("deviceId");
        String orders = params.getString("orders");
        String auth = params.getString("auth");

        String aliUid = "2088412156262616";
        String terminalParams = params.getString("terminal_params");
        String price = params.getString("price");
        jsonObject.put("success", false);
        jsonObject.put("msg", "请使用电子饭卡");
        return jsonObject;
    }

    private OuterExtends addOutOuterExtends(String name, String value) {
        OuterExtends outerExtends = new OuterExtends();
        outerExtends.setTitle(name);
        outerExtends.addDetail(name, value);
        return outerExtends;
    }

    private String getDinner(MacMainpSbruan macMainpSbruan) throws Exception {
        String hourMin = new SimpleDateFormat("HH:mm").format(new Date());
        List<MacMainpSbruanDinner> macMainpSbruanDinnerList = macMainpSbruanDinnerService
                .list(new QueryWrapper<MacMainpSbruanDinner>().lambda().eq(MacMainpSbruanDinner::getDeviceId, macMainpSbruan.getId()));
        for (MacMainpSbruanDinner goo : macMainpSbruanDinnerList) {
            if (DateUtil.hourMinuteBetween(hourMin, goo.getStartTime(), goo.getEndTime())) {
                return goo.getDinner();
            }
        }
        throw new Exception("未找到该餐次");
    }

    public JSONObject dzkPay(JSONObject params) {
        JSONObject jsonObject = new JSONObject();
        String deviceId = params.getString("deviceId");
        MacMainpSbruan macMainpSbruan = macMainpSbruanService.getOne(new QueryWrapper<MacMainpSbruan>().lambda().eq(MacMainpSbruan::getMac, deviceId));
        QrRestrictionsModel qrRestrictionsModel = JSONObject.toJavaObject(JSONObject.parseObject(macMainpSbruan.getQrRestrictions()), QrRestrictionsModel.class);
        Fk fk = null;
        switch (qrRestrictionsModel.getDzkRestrictions()) {
            case 0:
                jsonObject.put("success", false);
                jsonObject.put("msg", "当前模式尚未开通");
                return jsonObject;
            case 1:
                //使用BASE64解码方式
                String authStr = params.getString("authCode");
                byte[] bytes = Base64.getDecoder().decode(authStr);
                String json = new String(bytes);
                try {
                    String cardno = json.split(",")[0].split("=")[1];
                    String dates = json.split(",")[2].split("=")[1];
                    String nowDate = new SimpleDateFormat("yyyyMMddHHmmss").format(new Date(System.currentTimeMillis() - (2 * (60 * 1000) * 60)));
                    if (new BigDecimal(nowDate).compareTo(new BigDecimal(dates)) > 0) {
                        throw new RuntimeException("二维码已过期");
                    }
                    fk = fkService.getOne(new QueryWrapper<Fk>().lambda().eq(Fk::getCardno, cardno));
                } catch (Exception e) {
                    jsonObject.put("success", false);
                    jsonObject.put("msg", e.getMessage());
                    return jsonObject;
                }
                break;
            case 2:
                //通过数据库读取，获取一次解码
                fk = fkService.getFkByQr2(params.getString("auth"));
                break;
        }
        String price = params.getString("price");
        String orders = params.getString("orders");
        jsonObject.putAll(params);
        try {

            if (fk == null) {
                throw new RuntimeException("非法卡");
            }
            Kl kl = klService.getOne(new QueryWrapper<Kl>().lambda().eq(Kl::getBm, fk.getKl()));
            if (kl != null && kl.getValid() == 1) {
                //判断有效期
                if (fk.getValiddate().compareTo(new Date()) < 0) {
                    throw new RuntimeException("超过有效期");
                }
            }
            try {
                String dinner = getDinner(macMainpSbruan).trim();
                macMainpSbruan.setDinner(dinner);
            } catch (Exception e) {
                e.printStackTrace();
                throw new RuntimeException("餐次获取失败");
            }

            Map<String, String> resMap = reserveService.hexiaoReserve(Integer.parseInt(fk.getCardno()), macMainpSbruan.getDinner());
            if ("-1".equals(resMap.get("code")) || "-2".equals(resMap.get("code"))) {
                //支付失败
                throw new RuntimeException(resMap.get("msg"));
            } else if ("1".equals(resMap.get("code"))) {
                //支付成功，都不需要操作
                log.info("支付成功");
            } else if ("0".equals(resMap.get("code"))) {
                //可以支付，但支付不成功
                BigDecimal prices = new BigDecimal(resMap.get("payPrice"));
                int orderCount = Integer.parseInt(resMap.get("reserveSize"));
                reserveService.toPayByCardNo(deviceId, prices.multiply(new BigDecimal(100)).intValue(),
                        fk.getCardno(), orders, orderCount + 1);
                price = prices.toPlainString();
            }
            if (StringUtils.isEmpty(price)) {
                price = "0";
            }
            jsonObject.put("fk", fk);
            jsonObject.put("success", true);
            jsonObject.put("msg", "支付成功");
            jsonObject.put("userName", fk.getName());
            jsonObject.put("amount", price);
            List<OuterExtends> outerExtendsList = new ArrayList<>();
            outerExtendsList.add(addOutOuterExtends("姓名", fk.getName()));
            outerExtendsList.add(addOutOuterExtends("消费金额", price));
            outerExtendsList.add(addOutOuterExtends("卡余额", fk.getKye()));
            outerExtendsList.add(addOutOuterExtends("补贴余额", fk.getBtye()));
            jsonObject.put("outerExtends", outerExtendsList);
        } catch (Exception e) {
            e.printStackTrace();
            jsonObject.put("success", false);
            jsonObject.put("msg", e.getMessage());
        }
        return jsonObject;
    }
}
